package com.tlgen.orm.utils;

import com.tlgen.orm.annotation.AsLogicalField;
import com.tlgen.orm.annotation.AsNotField;
import com.tlgen.orm.common.BaseEntity;
import com.tlgen.orm.common.PageResult;
import com.tlgen.orm.common.Model;
import com.tlgen.orm.factory.ModelFactory;
import com.tlgen.orm.factory.QueryOperator;
import com.tlgen.orm.model.QueryParams;
import org.apache.commons.collections4.CollectionUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

import static com.tlgen.orm.constant.SQLScript.*;
import static com.tlgen.orm.factory.QueryFactory.mappingOperator;
import static com.tlgen.orm.utils.ORMUtils.getPrimaryKey;
import static com.tlgen.orm.utils.ORMUtils.getTableName;
import static com.tlgen.orm.utils.StringUtils.uncapUnderline;

public class SQLGenUtils {

    public static <T> List<T> selectAll(Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE);
        TraceLog.out(SQL);
        return ModelFactory.selectResult(SQL, tClass);
    }

    public static <T> List<T> selectAll(QueryOperator<T> queryOperator, Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(queryOperator.getParamsList()));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY");
        TraceLog.out(SQL);
        return ModelFactory.selectResult(SQL, tClass);
    }

    public static <T> T selectOne(QueryOperator<T> queryOperator, Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(queryOperator.getParamsList()));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY")
                .concat(SEPARATOR_SPACE)
                .concat("LIMIT 1");
        TraceLog.out(SQL);
        return ModelFactory.selectSingleResult(SQL, tClass);
    }

    public static <T> T selectOne(QueryOperator<T> queryOperator, QueryOperator<T> queryOperatorDefinition, Class<T> tClass) {
        // 添加自定义复杂条件查询
        if (CollectionUtils.isNotEmpty(queryOperatorDefinition.getParamsList())) {
            for (QueryParams queryParams : queryOperatorDefinition.getParamsList()) {
                queryOperator.getParamsList().add(queryParams);
            }
        }
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(queryOperator.getParamsList()));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY")
                .concat(SEPARATOR_SPACE)
                .concat("LIMIT 1");
        TraceLog.out(SQL);
        return ModelFactory.selectSingleResult(SQL, tClass);
    }

    public static <T> Object save(Object o) {
        Class<?> aClass = o.getClass();
        String primaryKey = ORMUtils.getPrimaryKey(aClass);
        Object id = null;
        // 收集属性名
        List<String> columns = new ArrayList<>();
        // 收集属性对应的值
        List<Object> values = new ArrayList<>();
        for (Field field : aClass.getDeclaredFields()) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            // 判断是否是主键, 并判断注解属性是否存在自定义值
            if (Objects.equals(primaryKey, fieldName) && Objects.isNull(fieldValue)) {
                // 获取分布雪花 ID
                Long aLong = SnowflakeIdWorker.generateId();
                fieldValue = aLong;
                id = aLong;
            }
            columns.add(uncapUnderline(fieldName));
            values.add(fieldValue);
        }
        // 判断该实体类是否继承于父类
        if (!Objects.equals("Object", aClass.getSuperclass().getSimpleName())) {
            // 判断该实体类是否继承于基类, 如果继承于基类, 获取基类的属性和值
            Class<BaseEntity> baseEntityClass = BaseEntity.class;
            if (Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : baseEntityClass.getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    if (declaredField.isAnnotationPresent(AsNotField.class)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    // 判断是否是主键, 并判断注解属性是否存在自定义值
                    if (Objects.equals(primaryKey, fieldName) && Objects.isNull(fieldValue)) {
                        // 获取分布雪花 ID
                        Long aLong = SnowflakeIdWorker.generateId();
                        fieldValue = aLong;
                        id = aLong;
                    }
                    // 是否为逻辑删除的字段属性
                    if (declaredField.isAnnotationPresent(AsLogicalField.class)) {
                        fieldValue = 0;
                    }
                    // 处理时间类型
                    if (Objects.equals("Date", declaredField.getType().getSimpleName()) && Objects.nonNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(fieldValue);
                    }
                    if (Objects.equals("createTime", fieldName) && Objects.isNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(new Date());
                    }
                    values.add(fieldValue);
                }
            } else {  // 判断该实体类如果没有继承于基类, 那么也需要获取它的父类中属性和值
                for (Field declaredField : aClass.getSuperclass().getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    // 判断是否是主键, 并判断注解属性是否存在自定义值
                    if (Objects.equals(primaryKey, fieldName) && Objects.isNull(fieldValue)) {
                        // 获取分布雪花 ID
                        Long aLong = SnowflakeIdWorker.generateId();
                        fieldValue = aLong;
                        id = aLong;
                    }
                    // 处理时间类型
                    if (Objects.equals("Date", declaredField.getType().getSimpleName()) && Objects.nonNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(fieldValue);
                    }
                    if (Objects.equals("createTime", fieldName) && Objects.isNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(new Date());
                    }
                    values.add(fieldValue);
                }
            }
        }
        // 处理值
        StringBuffer stringBuffer = new StringBuffer();
        values.forEach(x -> {
            if (null != x) {
                stringBuffer.append(SEPARATOR_SINGLE_QUOTA.concat(String.valueOf(x)).concat("', "));
            } else {
                stringBuffer.append(x).append(", ");
            }
        });
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = INSERT_PREFIX
                .concat(getTableName(aClass))
                .concat(SEPARATOR_OPEN)
                .concat(String.join(SEPARATOR_COMMA, columns))
                .concat(SEPARATOR_CLOSE)
                .concat(INSERT_VALUES)
                .concat(SEPARATOR_OPEN)
                .concat(bufferString)
                .concat(SEPARATOR_CLOSE);
        TraceLog.out(SQL);
        ModelFactory.execute(o, SQL);
        return id;
    }

    public static <T> void update(QueryOperator<T> queryOperator, Object o) {
        List<QueryParams> paramsList = queryOperator.getParamsList();
        // 获取查询条件
        String mappingOperator = mappingOperator(paramsList);
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        // 收集属性名
        List<String> columns = new ArrayList<>();
        // 收集属性对应的值
        List<Object> values = new ArrayList<>();
        for (Field field : aClass.getDeclaredFields()) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (!Objects.equals(primaryKeyName, fieldName)) {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 判断该实体类是否继承于父类
        if (!Objects.equals("Object", aClass.getSuperclass().getSimpleName())) {
            // 判断该实体类是否继承于基类, 如果继承于基类, 获取基类的属性和值
            Class<BaseEntity> baseEntityClass = BaseEntity.class;
            if (Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : baseEntityClass.getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    // 处理时间类型
                    if (Objects.equals("Date", declaredField.getType().getSimpleName()) && Objects.nonNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(fieldValue);
                    }
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(new Date());
                    }
                    values.add(fieldValue);
                }
            } else { // 判断该实体类如果没有继承于基类, 那么也需要获取它的父类中属性和值
                for (Field declaredField : aClass.getSuperclass().getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    // 处理时间类型
                    if (Objects.equals("Date", declaredField.getType().getSimpleName()) && Objects.nonNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(fieldValue);
                    }
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        fieldValue = sdf.format(new Date());
                    }
                    values.add(fieldValue);
                }
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (
                int i = 0; i < columns.size() && values.get(i) != null; i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(String.valueOf(values.get(i)))
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }

        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }

        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(mappingOperator);
        SQL = SQL.replaceFirst("AND", "WHERE");
        TraceLog.out(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void updateSelective(QueryOperator<T> queryOperator, Object o) {
        List<QueryParams> paramsList = queryOperator.getParamsList();
        // 获取查询条件
        String mappingOperator = mappingOperator(paramsList);
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        // 收集属性名
        List<String> columns = new ArrayList<>();
        // 收集属性对应的值
        List<Object> values = new ArrayList<>();
        for (Field field : aClass.getDeclaredFields()) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (!Objects.equals(primaryKeyName, fieldName)) {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 判断该实体类是否继承于父类
        if (!Objects.equals("Object", aClass.getSuperclass().getSimpleName())) {
            // 判断该实体类是否继承于基类, 如果继承于基类, 获取基类的属性和值
            Class<BaseEntity> baseEntityClass = BaseEntity.class;
            if (Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : baseEntityClass.getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    if (Objects.equals("createTime", fieldName) && Objects.isNull(fieldValue)) {
                        values.add(new Date());
                    } else {
                        values.add(fieldValue);
                    }
                }
            }
            // 判断该实体类如果没有继承于基类, 那么也需要获取它的父类中属性和值
            if (!Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : aClass.getSuperclass().getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        values.add(new Date());
                    } else {
                        values.add(fieldValue);
                    }
                }
            }
        }
        // 1.主键 id 不参与 set 语句
        // 2.如果值为空的属性不参与 set 语句
        // 3.作为条件的属性不参与 set 语句
        List<String> queryColumns = paramsList.stream().map(QueryParams::getColumn).collect(Collectors.toList());
        for (int i = values.size() - 1; i < values.size(); i--) {
            if (Objects.equals(columns.get(i), primaryKeyName)) {
                values.remove(i);
                columns.remove(i);
            }
            if (Objects.isNull(values.get(i))) {
                values.remove(i);
                columns.remove(i);
            }
            if (queryColumns.contains(columns.get(i))) {
                values.remove(i);
                columns.remove(i);
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < columns.size() && values.get(i) != null; i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(String.valueOf(values.get(i)))
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(mappingOperator);
        SQL = SQL.replaceFirst("AND", "WHERE");
        TraceLog.out(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void update(Object o) {
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        Object id = null;
        // 收集属性名
        List<String> columns = new ArrayList<>();
        // 收集属性对应的值
        List<Object> values = new ArrayList<>();
        for (Field field : aClass.getDeclaredFields()) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (Objects.equals(primaryKeyName, fieldName)) {
                id = fieldValue;
            } else {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 判断该实体类是否继承于父类
        if (!Objects.equals("Object", aClass.getSuperclass().getSimpleName())) {
            // 判断该实体类是否继承于基类, 如果继承于基类, 获取基类的属性和值
            Class<BaseEntity> baseEntityClass = BaseEntity.class;
            if (Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : baseEntityClass.getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        values.add(new Date());
                    } else {
                        values.add(fieldValue);
                    }
                }
            }
            // 判断该实体类如果没有继承于基类, 那么也需要获取它的父类中属性和值
            if (!Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : aClass.getSuperclass().getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        values.add(new Date());
                    } else {
                        values.add(fieldValue);
                    }
                }
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < columns.size(); i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(Objects.nonNull(values.get(i)) ? String.valueOf(values.get(i)) : "null")
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(SEPARATOR_WHERE)
                .concat(primaryKeyName)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA)
                .concat(String.valueOf(id))
                .concat(SEPARATOR_SINGLE_QUOTA);
        SQL = SQL.replaceAll("'null'", "null");
        TraceLog.out(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void updateSelective(Object o) {
        Class<?> aClass = o.getClass();
        String primaryKeyName = ORMUtils.getPrimaryKey(aClass);
        Object id = null;
        // 收集属性名
        List<String> columns = new ArrayList<>();
        // 收集属性对应的值
        List<Object> values = new ArrayList<>();
        for (Field field : aClass.getDeclaredFields()) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            if (Objects.equals(primaryKeyName, fieldName)) {
                id = fieldValue;
            } else {
                values.add(fieldValue);
                columns.add(uncapUnderline(fieldName));
            }
        }
        // 判断该实体类是否继承于父类
        if (!Objects.equals("Object", aClass.getSuperclass().getSimpleName())) {
            // 判断该实体类是否继承于基类, 如果继承于基类, 获取基类的属性和值
            Class<BaseEntity> baseEntityClass = BaseEntity.class;
            if (Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : baseEntityClass.getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        values.add(new Date());
                    } else {
                        values.add(fieldValue);
                    }
                }
            }
            // 判断该实体类如果没有继承于基类, 那么也需要获取它的父类中属性和值
            if (!Objects.equals(baseEntityClass.getSimpleName(), aClass.getSuperclass().getSimpleName())) {
                for (Field declaredField : aClass.getSuperclass().getDeclaredFields()) {
                    declaredField.setAccessible(true);
                    // 不映射为数据库中字段属性
                    AsNotField annotation = declaredField.getAnnotation(AsNotField.class);
                    if (Objects.nonNull(annotation)) {
                        continue;
                    }
                    String fieldName = declaredField.getName();
                    columns.add(uncapUnderline(fieldName));
                    Object fieldValue = ReflectionUtils.getFieldValue(o, fieldName);
                    if (Objects.equals("updateTime", fieldName) && Objects.isNull(fieldValue)) {
                        values.add(new Date());
                    } else {
                        values.add(fieldValue);
                    }
                }
            }
        }
        // 1.主键 id 不参与 set 语句
        // 2.如果值为空的属性不参与 set 语句
        for (int i = values.size() - 1; i < values.size(); i--) {
            if (Objects.equals(columns.get(i), primaryKeyName)) {
                values.remove(i);
                columns.remove(i);
            }
            if (Objects.isNull(values.get(i))) {
                values.remove(i);
                columns.remove(i);
            }
        }
        // 处理值
        StringBuilder stringBuffer = new StringBuilder();
        for (int i = 0; i < columns.size(); i++) {
            stringBuffer.append(columns.get(i)
                    .concat(SEPARATOR_EQUAL)
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(Objects.nonNull(values.get(i)) ? String.valueOf(values.get(i)) : "null")
                    .concat(SEPARATOR_SINGLE_QUOTA)
                    .concat(SEPARATOR_COMMA)
            );
        }
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        String SQL = UPDATE_PREFIX
                .concat(getTableName(aClass))
                .concat(UPDATE_SET)
                .concat(bufferString)
                .concat(SEPARATOR_WHERE)
                .concat(primaryKeyName)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA)
                .concat(String.valueOf(id))
                .concat(SEPARATOR_SINGLE_QUOTA);
        SQL = SQL.replaceAll("'null'", "null");
        TraceLog.out(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void deleteById(Object id, Class<?> tClass) {
        String key = getPrimaryKey(tClass);
        String SQL = DELETE_PREFIX
                .concat(getTableName(tClass)
                        .concat(SEPARATOR_WHERE)
                        .concat(key)
                        .concat(SEPARATOR_EQUAL)
                        .concat(SEPARATOR_SINGLE_QUOTA.concat(String.valueOf(id)).concat(SEPARATOR_SINGLE_QUOTA)));
        System.out.println(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void deleteLogicalById(Object id, Class<T> tclass) {
        String primaryKeyName = getPrimaryKey(tclass);
        String delFlagKey = ORMUtils.getLogicalDeleteField(tclass);
        String SQL = UPDATE_PREFIX
                .concat(getTableName(tclass))
                .concat(UPDATE_SET)
                .concat(delFlagKey)
                .concat(SEPARATOR_EQUAL)
                .concat("1")
                .concat(SEPARATOR_WHERE)
                .concat(primaryKeyName)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA)
                .concat(String.valueOf(id))
                .concat(SEPARATOR_SINGLE_QUOTA);
        System.out.println(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void delete(Class<T> tclass) {
        String SQL = DELETE_PREFIX.concat(getTableName(tclass));
        System.out.println(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> void delete(QueryOperator<T> operator, Class<T> tclass) {
        List<QueryParams> paramsList = operator.getParamsList();
        // 获取查询条件
        String mappingOperator = mappingOperator(paramsList).replaceFirst("AND", "WHERE");
        String SQL = DELETE_PREFIX.concat(getTableName(tclass)).concat(mappingOperator);
        System.out.println(SQL);
        ModelFactory.execute(SQL);
    }

    public static <T> T selectById(Object id, Class<T> tClass) {
        String key = getPrimaryKey(tClass);
        String SQL = SELECT_PREFIX.concat(getTableName(tClass)
                .concat(SEPARATOR_SPACE)
                .concat(SEPARATOR_WHERE)
                .concat(key)
                .concat(SEPARATOR_EQUAL)
                .concat(SEPARATOR_SINGLE_QUOTA.concat(String.valueOf(id)).concat(SEPARATOR_SINGLE_QUOTA)));
        TraceLog.out(SQL);
        return ModelFactory.selectSingleResult(SQL, tClass);
    }

    public static <T> void saveBatch(List<T> tList) {
        List<String> stringList = new ArrayList<>();
        for (T o : tList) {
            String INNER_SQL = selectInnerSQL(o);
            stringList.add(INNER_SQL);
        }
        // 分片插入（每 1000 条执行一次批量插入）
        int batchSize = 1000;
        int total = stringList.size();
        // 需要执行的次数
        int insertTimes = total / batchSize;
        // 最后一次执行需要提交的记录数（防止可能不足 1000 条）
        int lastSize = batchSize;
        if (total % batchSize != 0) {
            insertTimes++;
            lastSize = total % batchSize;
        }
        for (int j = 0; j < insertTimes; j++) {
            if (insertTimes == j + 1) {
                batchSize = lastSize;
            }
            List<String> subList = stringList.subList(j * batchSize, (j * batchSize + batchSize));
            String saveBatchPrefix = "";
            List<String> valueList = new ArrayList<>();
            for (String s : subList) {
                String[] split = s.split("VALUES");
                valueList.add(split[1]);
                saveBatchPrefix = split[0];
            }
            String SQL = saveBatchPrefix.concat(INSERT_VALUES).concat(String.join(",", valueList));
            TraceLog.out(SQL);
            // 分片执行批量插入
            ModelFactory.execute(SQL);
        }
    }

    private static <T> String selectInnerSQL(T o) {
        Class<?> aClass = o.getClass();
        String primaryKey = ORMUtils.getPrimaryKey(aClass);
        // 收集属性名
        List<String> columns = new ArrayList<>();
        // 收集属性对应的值
        List<Object> values = new ArrayList<>();
        for (Field field : aClass.getDeclaredFields()) {
            String fieldName = field.getName();
            Object fieldValue = ReflectionUtils.getFieldValue(o, field.getName());
            // 判断是否是主键, 并判断注解属性是否存在自定义值
            if (Objects.equals(primaryKey, field.getName()) && Objects.isNull(fieldValue)) {
                // 获取分布雪花 ID
                Long aLong = SnowflakeIdWorker.generateId();
                values.add(aLong);
            } else {
                values.add(fieldValue);
            }
            columns.add(uncapUnderline(fieldName));
        }
        // 处理值
        StringBuffer stringBuffer = new StringBuffer();
        values.forEach(x -> {
            if (null != x) {
                stringBuffer.append(SEPARATOR_SINGLE_QUOTA.concat(String.valueOf(x)).concat("', "));
            } else {
                stringBuffer.append(x).append(", ");
            }
        });
        String bufferString = stringBuffer.toString();
        if (!bufferString.isEmpty()) {
            bufferString = bufferString.substring(0, stringBuffer.length() - 2);
        }
        // 组装 SQL
        return INSERT_PREFIX
                .concat(getTableName(aClass))
                .concat(SEPARATOR_OPEN)
                .concat(String.join(SEPARATOR_COMMA, columns))
                .concat(SEPARATOR_CLOSE)
                .concat(INSERT_VALUES)
                .concat(SEPARATOR_OPEN)
                .concat(bufferString)
                .concat(SEPARATOR_CLOSE);
    }

    public static <T> PageResult<T> selectPage(Integer pageNum, Integer pageSize, QueryOperator<T> queryOperator, Class<T> tClass) {
        String SQL = SELECT_PREFIX
                .concat(getTableName(tClass))
                .concat(SEPARATOR_SPACE)
                .concat(mappingOperator(queryOperator.getParamsList()));
        SQL = SQL.replaceFirst("AND", "WHERE")
                .replace("WHERE  GROUP BY", "GROUP BY")
                .replace("WHERE  ORDER BY", "ORDER BY")
                .replace("AND  ORDER BY", "ORDER BY");
        BinaryOperator<Integer> multiply = (x, y) -> (x - 1) * y;
        SQL = SQL.concat(SEPARATOR_LIMIT)
                .concat(String.valueOf(multiply.apply(pageNum, pageSize)))
                .concat(SEPARATOR_COMMA)
                .concat(String.valueOf(pageSize));
        TraceLog.out(SQL);
        return ModelFactory.selectPageResult(SQL, tClass);
    }

    public static <T> List<T> tTree(Class<T> tClass) {
        return TreeUtils.tTree(Model.selectAll(tClass));
    }

}
